from PyQt5 import QtWidgets, QtCore
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt, pyqtSignal
# CTP行情库
from vnctpmd import *
import globalvar
import threading
from threading import Thread
import module_strategy

def log_wirtemd(filepath, content):
    with open(filepath, 'a') as wf:
        wf.write(content + "\n")
    row_cnt = globalvar.ui.table_historymd.rowCount()  # 返回当前行数（尾部）
    addrow = False
    if row_cnt > 0:
        indicatorsname = globalvar.ui.table_historymd.item(row_cnt - 1, 1).text()
        if indicatorsname != filepath:
            addrow = True
    else:
        addrow = True
    if addrow == True:
        # 增加一行
        globalvar.ui.table_historymd.insertRow(row_cnt)  # 尾部插入一行新行表格
        column_cnt = globalvar.ui.table_historymd.columnCount()  # 返回当前列数
        item = QTableWidgetItem(str(row_cnt + 1))
        globalvar.ui.table_historymd.setItem(row_cnt, 0, item)
        item = QTableWidgetItem(str(filepath))
        globalvar.ui.table_historymd.setItem(row_cnt, 1, item)

def log_todaymd(mystr):
    _translate = QtCore.QCoreApplication.translate
    item = QtWidgets.QListWidgetItem()
    globalvar.ui.list_listmdlog.addItem(item)
    item = globalvar.ui.list_listmdlog.item(globalvar.ui.list_listmdlog.count() - 1)
    tstr = time.strftime("%Y-%m-%d %H:%M:%S ", time.localtime())
    item.setText(_translate("MainWindow", tstr + mystr))
    filepath = time.strftime("logfile\\md\\%Y%m%d.txt", time.localtime())
    log_wirtemd(filepath, tstr + mystr)

# 更新K线图
class UIUpdateklineThread(threading.Thread):
    def __init__(self, InstrumentID):
        super(UIUpdateklineThread, self).__init__()
        self.InstrumentID = InstrumentID

    def run(self):
        globalvar.ui.updateklineUi(self.InstrumentID)


# 更新分时图
class UIUpdatemarketThread(threading.Thread):
    def __init__(self, newdata):
        super(UIUpdatemarketThread, self).__init__()
        self.newdata = newdata

    def run(self):
        globalvar.ui.updatemarketUi(self.newdata)


def update_depthMarketData(a):
    if globalvar.selectinstrumenid == a.InstrumentID:
        # uimarketthread = UIUpdatemarketThread(a.LastPrice)
        # uimarketthread.start()
        uiklinethread = UIUpdateklineThread(a.InstrumentID)
        uiklinethread.start()


# MyCTPMarket类继承自CTPMarket类
class MyCTPMarket(vnctpmd, QtCore.QThread):
    loginstate = False

    def ReqUserLogin(self):
        pass

    def OnRtnDepthMarketData(self, tickdatacontents):
        tickdata = tickdatacontents[0]
        update_depthMarketData(tickdata)
        # 将Tick数据发送给策略管理器
        module_strategy.StrategyManager(tickdata)
        self.signal_md_tick.emit([tickdata.InstrumentID, tickdata.LastPrice, tickdata.Volume,
                                  tickdata.TradingDay, tickdata.UpdateTime,
                                  tickdata.UpdateMillisec])
        try:
            globalvar.thistoday = int(tickdata.TradingDay)
        except Exception as e:
            pass

    # 合约订阅回调
    def OnRspSubMarketData(self, a):
        print(u'订阅合约成功OnRspSubMarketData' + a[0].InstrumentID)
        log_todaymd('订阅合约成功OnRspSubMarketData' + a[0].InstrumentID)

    # 合约订阅回调
    def OnRspUnSubMarketData(self, a):
        print(u'反订阅合约成功OnRspUnSubMarketData' + a[0].InstrumentID)
        log_todaymd('反订阅合约成功OnRspUnSubMarketData' + a[0].InstrumentID)

    # 登录回调
    def OnRspUserLogin(self, a):
        # print(a.contents.a1, a.contents.a2)
        print(u'行情登录成功OnRspUserLogin')
        log_todaymd('行情登录成功OnRspUserLogin')
        # self.SubscribeMarketData('rb2110')
        self.loginstate = True
        globalvar.ui.SetBarMDState(3)

    # 退出登录回调
    def OnRspUserLogout(self, a):
        # print(a.contents.a1, a.contents.a2)
        print(u'行情登出成功OnRspUserLogout')
        log_todaymd('行情登出成功OnRspUserLogout')
        self.loginstate = False

    # 建立连接回调
    def OnFrontConnected(self):
        print("连接行情服务器成功OnFrontConnected")
        log_todaymd('连接行情服务器成功OnFrontConnected')
        globalvar.ui.SetBarMDState(2)
        globalvar.mdinit = True

    # 断开连接回调
    def OnFrontDisconnected(self, a):
        print("断开与行情服务器连接OnFrontDisconnected")
        log_todaymd('断开与行情服务器连接OnFrontDisconnected')
        self.loginstate = False
        globalvar.ui.SetBarMDState(1)
        globalvar.mdinit = True

class RegMdThreadOnFrontConnected(Thread):
    def __init__(self, name, md):
        super().__init__()
        self.name = name
        self.md = md

    def run(self):
        self.md.VNRegOnFrontConnected()


class RegMdThreadOnFrontDisconnected(Thread):
    def __init__(self, name, md):
        super().__init__()
        self.name = name
        self.md = md

    def run(self):
        self.md.VNRegOnFrontDisconnected()


class RegMdThreadOnRspUserLogin(Thread):
    def __init__(self, name, md):
        super().__init__()
        self.name = name
        self.md = md

    def run(self):
        self.md.VNRegOnRspUserLogin()


class RegMdThreadOnRspUserLogout(Thread):
    def __init__(self, name, md):
        super().__init__()
        self.name = name
        self.md = md

    def run(self):
        self.md.VNRegOnRspUserLogout()


class RegMdThreadOnRtnDepthMarketData(Thread):
    def __init__(self, name, md):
        super().__init__()
        self.name = name
        self.md = md

    def run(self):
        self.md.VNRegOnRtnDepthMarketData()


class RegMdThreadOnRspSubMarketData(Thread):
    def __init__(self, name, md):
        super().__init__()
        self.name = name
        self.md = md

    def run(self):
        self.md.VNRegOnRspSubMarketData()


class RegMdThreadOnRspUnSubMarketData(Thread):
    def __init__(self, name, md):
        super().__init__()
        self.name = name
        self.md = md

    def run(self):
        self.md.VNRegOnRspUnSubMarketData()


class RegMdThreadOnStrategyCalculate(Thread):
    def __init__(self, name, md, list_hwnd):
        super().__init__()
        self.name = name
        self.md = md
        self.list_hwnd = list_hwnd

    def run(self):
        for k in self.list_hwnd:
            self.md.VNRegOnStrategyCalculate(k)


def function_md(md):
    # 注册异步回调函数线程（多线程回调，可绕过GIL锁）
    RegMdThreadOnFrontConnected('OnFrontConnected', md).start()
    RegMdThreadOnFrontDisconnected('OnFrontDisconnected', md).start()
    RegMdThreadOnRspUserLogin('OnRspUserLogin', md).start()
    RegMdThreadOnRspUserLogout('OnRspUserLogout', md).start()
    RegMdThreadOnRtnDepthMarketData('OnRtnDepthMarketData', md).start()
    RegMdThreadOnRspSubMarketData('OnRspSubMarketData', md).start()
    RegMdThreadOnRspUnSubMarketData('OnRspUnSubMarketData', md).start()

    time.sleep(1)
    result = md.InitMD()

    if result == 0:
        log_todaymd('行情接口配置文件读取成功')
    elif result == 1:
        log_todaymd('行情接口配置文件读取错误，请检查vnctpmd.ini是否存在')
        return
    elif result == 2:
        log_todaymd('行情接口配置文件读取错误，请检查vnctpmd.ini配置文件至少要配置一个行情IP地址')
        return

    '''
    #启动策略管理器
    #md.GetStrategyMode()
    if 0:
        sm = MyStrategyMangement()
        sm.GetStrategyMode()
        RegMdThreadOnStrategyCalculate('RegMdThreadOnStrategyCalculate', md,sm.list_hwnd).start()
    '''

    # generateinstrumentID()
    # md.RegisterFront()
    # Login()，不需要参数，Login读取QuickLibTD.ini的配置信息，并登录
    # 返回0， 表示登录成功，
    # 返回1， FutureTDAccount.ini错误
    # 返回2， 登录超时
    # 第一次是自动登录，退出登录后，如需再登陆，需添加以下登陆代码
    # 调用交易接口元素，通过 “ 接口变量.元素（接口类内部定义的方法或变量） ” 形式调用
    # Login()，不需要参数，Login读取QuickLibTD.ini的配置信息，并登录
    # 返回0， 表示登录成功，
    # 返回1， FutureTDAccount.ini错误
    # 返回2， 登录超时
    # print ('login: ', retLogin)

    # if md.Login() == 0:
    if md.ReqUserLogin() == 0:
        log_todaymd('发送登录行情服务器请求成功')
    else:
        log_todaymd('发送登录行情服务器请求失败')
    # 若登录成功，会触发 OnRspUserLogin 回调
    # 若登录失败，会触发 OnRspUserLogout 回调
    # 登录成功后，就可以执行情订阅等操作了，所以行情订阅放置在OnRspUserLogin()中执行

    # 设置拒绝接收行情服务器数据的时间，有时候（特别是模拟盘）在早晨6-8点会发送前一天的行情数据，若不拒收的话，会导致历史数据错误，本方法最多可以设置4个时间段进行拒收数据
    # md.SetRejectdataTime(0.0400, 0.0840, 0.1530, 0.2030, NULL, NULL, NULL, NULL);

    # main()函数内的以上部分代码只执行一次，以下while(1)循环内的代码，会一直循环执行，可在这个循环内需增加策略判断，达到下单条件即可下单

    # 判断当前时间是否在交易时间内，如果在返回真，则开始执行
    # if (IsStockTrade()):
    # 取消订阅
    # md.UnSubscribeMarketData(u'rb1810')
    # 退出登录
    # md.ReqUserLogout()
    # md.SubscribeMarketData(u'rb2110')
    # time.sleep(1)  # 系统休眠0.1秒

    # 重新订阅行情
    # md.Subcribe(u'rb1810')
    while 1:  # 死循环，反复执行
        # print(md.LastPrice("rb2110"))
        # 打印该品种在行情接口的变量LastPrice (最新价)
        # print(md.BidPrice1('rb2110'))
        # 打印该品种在行情接口的变量BidPrice
        time.sleep(30)  # 系统休眠


class MDThread(QtCore.QThread):
    signal_md_tick = pyqtSignal(list)

    def __del__(self):
        self.wait()

    def __init__(self):
        super(MDThread, self).__init__()

    def run(self):
        time.sleep(1)
        globalvar.md = MyCTPMarket(self.signal_md_tick)
        globalvar.md.ui = globalvar.ui
        function_md(globalvar.md)
